#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../include/narryTree.h"

//------------------------------------------------------
//global variables
	int hashIndex=0;
	int i,size1,n;
	char name[50];
	char *s;
	struct fileDescriptor filefd;
	struct node *temp2;
	bstrootcreated=0;

//----------------------------------------------------------------------------------------------------------------
struct node * narraymount(char fileSystemName[])
{

	struct node *root;
	struct header h;
	//struct fileDescriptor fd;
	struct freeList fl;
	struct fileDescriptor filefd;
	int choice,size1,n,i;
	char locationPath[50],childName[50];
	FILE *fp;	
	fp=fopen(fileSystemName,"rb+");
	if(fp==NULL) 
	{
		printf("mountvfs_FAILURE ");
		printf(ERR_VFS_MOUNT_02);
		printf("\n");
		return NULL;
	}
	
//Create root------------------------------------------------------------------------

		fread(&h,sizeof(struct header),1,fp);
		n=h.maxfd;
		fd_count=n-1;
		size1=sizeof(struct header)+n*sizeof(struct freeList);
		fseek(fp,size1,SEEK_SET);
		fread(&filefd,sizeof(struct fileDescriptor),1,fp);
		root=(struct node *)malloc(sizeof(struct node ));
		root->fddata=(struct fileDescriptor *)malloc(sizeof(struct fileDescriptor));
		strcpy(root->fddata->fileName ,filefd.fileName);
		strcpy(root->fddata->locationPath ,filefd.locationPath);
		strcpy(root->fddata->fileType ,filefd.fileType);
		root->fddata->fileSize = filefd.fileSize;
		root->fddata->blockNumber = filefd.blockNumber;
		root->parent=NULL;
	 	root->lchild=NULL;
		root->rsibling=NULL;

		//printf("%s\n",root->fddata->fileName);
		//printf("%s\n",root->fddata->locationPath);
//create sub-directories(child)-------------------------------------------------------
	
	for(i=0;i<n;i++)
	{
		fread(&filefd,sizeof(struct fileDescriptor),1,fp);
		strcpy(childName,filefd.fileName);
		strcpy(locationPath,filefd.locationPath);
		if(filefd.isfull=='1')
		{
			//printf("%s\n",filefd.fileName);
			//printf("%s\n",filefd.locationPath);
			root=createChildMount(&filefd,root);
			



		}
		else
		break;
		
	}

	//printfolder(root);
	fclose(fp);
	return root;
}
//----------------------------------------------------------------------------------------------------------------
//Inserting directories in narry tree (after mounting)

struct node * createChild(char childName[],char locationPath[],struct node *root1)
{
	struct node *child,*temp,*temp1,*t,*tempp;
	temp=root1;
	temp1=root1;
	char tempstr[50];
	char tempstr1[50];
	child=(struct node *)malloc(sizeof(struct node ));
	child->fddata=(struct fileDescriptor *)malloc(sizeof(struct fileDescriptor));
	
	//printf("locpathhhhh:%s\n",locationPath);
	if(strcmp(locationPath,"/")==0)
	{
	strcpy(tempstr,"");
	//printf("%s\n",tempstr);
	}
	else
	{
	strcpy(tempstr,"/");
	//printf("%s\n",tempstr);
	}

	strcat(tempstr,childName);
	//strcat(childName,tempstr);
	strcpy(tempstr1,locationPath);
	strcat(tempstr1,tempstr);
	//printf("child location :%s\n",tempstr1);	
	
	strcpy(child->fddata->fileName,childName);
	strcpy(child->fddata->fileType,"dir");
	child->fddata->fileSize=0;
	strcpy(child->fddata->locationPath,tempstr1);
		
	child->fddata->blockNumber=-1;
	child->fddata->isfull='1';
	//printf("locationpath sent to findFolder:%s\n",locationPath);
	//printf("input1 sent to findFolder:%s\n",temp1->fddata->fileName);
	root1=findfolder(temp1,locationPath);
	//printf("Parent of %s is %s\n",root1->fddata->fileName,tempp->fddata->fileName);	
	root1=temp2;
	tempp=temp2->parent;
	//printf("parent value: %s\n",temp2->fddata->fileName);
	//printf("Parent's parent value: %s\n",tempp->fddata->fileName);
	
	if(strcmp(root1->fddata->fileType,"dir")!=0)
	{
		//printf("\n---------Path Invalid---------- !!\n\n");
		return temp;
	}
	if(root1->lchild==NULL)
	{	
				
		//printf("\nlchild\n");
		root1->lchild=child;
		child->parent=temp2;
		child->lchild=NULL;
		child->rsibling=NULL;
	}
	else
	{
		//printf("\nrsibling\n");
		root1=root1->lchild;
		while(root1->rsibling!=NULL)			
		{		
		root1=root1->rsibling;
		}

		child->parent=temp2;
		root1->rsibling=child;
		child->rsibling=NULL;
		child->lchild=NULL;
	}
	//printf("parent value of %s is %s\n",child->fddata->fileName,child->parent->fddata->fileName);
	fd_count--;
	insertBst(child->fddata);

	return temp;
}
		
//----------------------------------------------------------------------------------------------------------------
//create child by narraymount (while mounting from filesystem)

struct node * createChildMount(struct fileDescriptor *fd,struct node *root1)
{
	
	//char childName[20]=fd->fileName;
	//char locationPath[50]=fd->locationPath;
	struct node *child,*temp,*temp1,*t,*tempp;
	temp=root1;
	temp1=root1;
	char tempstr[50],str[100],newstr[50];
	char tempstr1[50];
	char updated_locpath[100];
	child=(struct node *)malloc(sizeof(struct node ));
	child->fddata=(struct fileDescriptor *)malloc(sizeof(struct fileDescriptor));
	/*
	int lp_length,cn_length,diff_length,i;	//location path length, childname length

	lp_length=strlen(fd->locationPath);
	cn_length=strlen(fd->fileName);		
	
	diff_length=lp_length-(cn_length+1);
	
	

	for(i=0;i<diff_length;i++){
	updated_locpath[i]=fd->locationPath[i];
	}
		
	updated_locpath[i]='\0';
	//printf("updated llocation: %s\n",updated_locpath); 
		*/

	strcpy(str,fd->locationPath);
	int i=0;
	int count=0;
	while(str[i]!='\0')
	{
	if(str[i]=='/')
	count=i;
	i++;
	}
	count++;
	int j=0;
	while(j<count)
	{
		newstr[j]=str[j];
		j++;
	}
	newstr[j]='\0';
	//printf("new loc:%s\n",newstr);
	strcpy(updated_locpath,newstr);

	
	
	strcpy(child->fddata->fileName,fd->fileName);
	strcpy(child->fddata->fileType,fd->fileType);
	child->fddata->fileSize=fd->fileSize;
	strcpy(child->fddata->locationPath,fd->locationPath);
		//printf("Location path written into fd of file: %s\n",child->fddata->locationPath);
		
	child->fddata->blockNumber=fd->blockNumber;
	child->fddata->isfull='1';
	//printf("loctation path before findfolder:%s\n",fd->locationPath);
	root1=findfolder(temp1,updated_locpath);
	
	//printf("Parent of %s is %s\n",root1->fddata->fileName,tempp->fddata->fileName);
	root1=temp2;
	tempp=root1->parent;
	//printf("parent value: %s\n",temp2->fddata->fileName);
	//printf("call return\n");
	if(strcmp(root1->fddata->fileType,"dir")!=0)
	{
		//printf("\n---------Path Invalid---------- !!\n\n");
		return temp;
	}
	if(root1->lchild==NULL)
	{	
				
		//printf("\nlchild\n");
		root1->lchild=child;
		child->parent=temp2;
		child->lchild=NULL;
		child->rsibling=NULL;
	}
	else
	{
		//printf("\nrsibling\n");
		root1=root1->lchild;
		while(root1->rsibling!=NULL)			
		{		
		root1=root1->rsibling;
		}

		child->parent=temp2;
		root1->rsibling=child;
		child->rsibling=NULL;
		child->lchild=NULL;
	}
			if(strcmp(child->fddata->fileType,"dir")!=0)
			{
			hashIndex=hash(child->fddata->fileName);
			//printf("in hash ???????????????????????????????	\n");
			insert(child->fddata,hashIndex);
			}
	fd_count--;
	insertBst(child->fddata);
	return temp;
}

		
//----------------------------------------------------------------------------------------------------------------
//Inserting data files in narry tree (after mounting)

struct node * insertChild(char childName[],char fType[],char locationPath[],struct node *root1,struct fileDescriptor *fd1)
{
	struct node *child,*temp,*temp1,*t;
	temp=root1;
	temp1=root1;
	char tempstr[50];
	char tempstr1[50];
	child=(struct node *)malloc(sizeof(struct node ));
	child->fddata=(struct fileDescriptor *)malloc(sizeof(struct fileDescriptor));
	

	if(strcmp(locationPath,"/")==0)
	strcpy(tempstr,"");
	else
	strcpy(tempstr,"/");

	
	strcat(tempstr,childName);
	//strcat(childName,tempstr);
	strcpy(tempstr1,locationPath);
	strcat(tempstr1,tempstr);
	//printf("child loaction :%s\n",tempstr1);	
	
	strcpy(child->fddata->fileName,childName);
//	strcpy(child->fddata->fileType,"text");
	strcpy(child->fddata->fileType,fType);
	child->fddata->fileSize=fd1->fileSize;
	strcpy(child->fddata->locationPath,tempstr1);
	child->fddata->isfull='1';
		
	child->fddata->blockNumber=fd1->blockNumber;
	//printf("location:%s",locationPath);
	root1=findfolder(temp1,locationPath);
	root1=temp2;
	//printf("parent value: %s\n",temp2->fddata->fileName);
	//printf("call return\n");
	if(strcmp(root1->fddata->fileType,"dir")!=0)
	{
		//printf("Path Invalid !!\n");
		return temp;
	}
	if(root1->lchild==NULL)
	{	
		
				
		//printf("\nlchild\n");
		root1->lchild=child;
		child->parent=temp2;
		child->lchild=NULL;
		child->rsibling=NULL;
	}
	else
	{
		//printf("\nrsibling\n");
		root1=root1->lchild;
		while(root1->rsibling!=NULL)
		{		
		root1=root1->rsibling;
		}


		child->parent=temp2;
		root1->rsibling=child;
		child->rsibling=NULL;
		child->lchild=NULL;
	}
		
		//strcpy(fd1->fileName,childName);
	
		hashIndex=hash(childName);
		insert(child->fddata,hashIndex);	//inserting into hash table
		fd_count--;
		insertBst(child->fddata);

		
		

	return temp;
}
//----------------------------------------------------------------------------------------------------------------
//delete function

struct node * deleteChild(char locationPath[],struct node *root1)
{
	struct node *child,*temp,*temp1,*temp3,*tempParent,*templsibling,*temprsibling,*t,*ptr,*prev,*next;
	temp=root1;
	temp1=root1;
	char tempstr[50];
	char choice;
	int neighboursfound=0;

//	printf("loctation path before findpreviousfolder:%s\n",locationPath);
	//printf("before find folder\n");
	root1=findfolder(temp1,locationPath);
	//printf("after find folder\n");
	root1=temp2;
	//printf("Folder to be deleted(root1): %s\n",root1->fddata->fileName);
	
	//printf("Folder to be deleted(temp2): %s\n",root1->fddata->fileName);
	//printf("Folder to be deleted: %s\n",root1->fddata->locationPath);
	
	/*
	
	*/
	tempParent=root1->parent;
	temprsibling=root1->rsibling;
	templsibling=root1->lchild;
	//printf("Parent of the Folder to be deleted: %s\n",tempParent->fddata->fileName);
	//printf("RSibling of the Folder to be deleted: %s\n",temprsibling->fddata->fileName);
	//printf("LChild of the Folder to be deleted: %s\n",templsibling->fddata->fileName);

	if(root1->lchild == NULL)
	{
	//printf("in if loop\n");


			if(root1 == tempParent->lchild)
			{
			//printf("in 2nd if loop\n");
			temp3=root1->rsibling;
			tempParent->lchild=temp3;
			//printf("%s is been deleted\n",root1->fddata->fileName);

			if(strcmp(root1->fddata->fileType,"dir")!=0)
						{
						//printf("node is a file\n");
						deleteChildfile(root1);
						}
			deleteBstElm(root1->fddata->locationPath);
			fd_count++;
			free(root1);
			}
			else
			{
			prev=NULL;	
			ptr=tempParent->lchild;
			next=ptr->rsibling;
						while(!neighboursfound)
						{
	
						if(ptr == root1)
						{
						neighboursfound=1;

						prev->rsibling=next;
						//printf("%s is been deleted\n",root1->fddata->fileName);
						if(strcmp(root1->fddata->fileType,"dir")!=0)
						{
						deleteChildfile(root1);
						//printf("node is a file\n");
						}
						deleteBstElm(root1->fddata->locationPath);
						fd_count++;
						free(root1);
	
						}
						else
						{
						prev=ptr;
						ptr=ptr->rsibling;
						next=ptr->rsibling;
						}
						}
			}
	}
	else
	{
		printf("deletedir_FAILURE ");
		printf(ERR_VFS_DELETEDIR_02);
		printf("\n");
		return temp;
	}
	
	/*
	else{
	//printf("%s is not empty\n",root1->fddata->fileName);
	//printf("If you still want to delete %s press y",root1->fddata->fileName);
	
			//do{
			printf("If you still want to delete %s press y or else press n\n",root1->fddata->fileName);
			scanf("%c",&choice);
			//}
			//while(choice!='y' || choice!='n');

			if(choice=='y')
			{
					if(root1 == tempParent->lchild)
					{
					temp3=root1->rsibling;
					tempParent->lchild=temp3;
					//printf("%s is been deleted\n",root1->fddata->fileName);

					if(strcmp(root1->fddata->fileType,"text")==0)
						{
						deleteChildfile(root1);
						printf("node is a file\n");
						}
					free(root1);
					fd_count++;
					deleteBstElm(root1->fddata->locationPath);
					}
					else
					{
					prev=NULL;	
					ptr=tempParent->lchild;
					next=ptr->rsibling;
							while(!neighboursfound)
							{
	
							if(ptr == root1)
							{
							neighboursfound=1;

							prev->rsibling=next;
							//printf("%s is been deleted\n",root1->fddata->fileName);

						if(strcmp(root1->fddata->fileType,"text")==0)
						{
						deleteChildfile(root1);
						printf("node is a file\n");
						}
							deleteBstElm(root1->fddata->locationPath);
							fd_count++;
							free(root1);
	
							}
							else
							{
							prev=ptr;
							ptr=ptr->rsibling;
							next=ptr->rsibling;
							}
							}
					}
	
			}
	}

	//printf("Previous folder: %s\n",tempParent->fddata->fileName);
	*/
	printf("deletedir_SUCCESS\n");
	return temp;

}
//-----------------------------------------------------------------------------------------------------------------------------


void deleteChildfile(struct node *root1)
{
//printf("in deleteChildfile\n");
						
						deleteHash(root1->fddata);
						struct freeList filefl;
						struct header hdr;
						int offset,blknumber=root1->fddata->blockNumber;
						FILE *filefldel;
						filefl.freel='0';
						filefldel=fopen(flsname,"rb+");
						offset=sizeof(hdr)+sizeof(filefl)*blknumber;
						fread(&hdr,sizeof(hdr),1,filefldel);
						int n=hdr.maxfd;
						//printf("maxfd %d\n",n);
						fseek(filefldel,offset,SEEK_SET);
						fwrite(&filefl,sizeof(filefl),1,filefldel);
						//printf("fl reset\n");

fseek(filefldel,sizeof(struct header),SEEK_SET);
	for(i=0;i<n;i++)
	{
		//printf("flist->");
		fread(&filefl,sizeof(struct freeList),1,filefldel);
		//printf("%c ",filefl.freel);
		
	}
	//printf("\n");

fclose(filefldel);

}

//----------------------------------------------------------------------------------------------------------------------------

struct node * movefilecall(char srclocationPath[], char destnlocationPath[], struct node *root1)
{
	struct node *child,*temp,*temp1,*temp3,*tempParent,*templsibling,*temprsibling,*t,*ptr,*prev,*next;
	temp=root1;
	temp1=root1;
	char tempstr[50];
	char choice;
	int neighboursfound=0;

//	printf("loctation path before findpreviousfolder:%s\n",locationPath);
	//printf("before find folder\n");
	root1=findfolder(temp1,srclocationPath);
	//printf("after find folder\n");
	root1=temp2;
	child=temp2;
	//printf("Folder to be moved(root1): %s\n",root1->fddata->fileName);

	//printf("Folder to be moved(temp2): %s\n",root1->fddata->fileName);
	//printf("Folder to be moved: %s\n",root1->fddata->locationPath);
	tempParent=root1->parent;
	temprsibling=root1->rsibling;
	templsibling=root1->lchild;
	//printf("Parent of the Folder to be moved: %s\n",tempParent->fddata->fileName);
	//printf("RSibling of the Folder to be deleted: %s\n",temprsibling->fddata->fileName);
	//printf("LChild of the Folder to be deleted: %s\n",templsibling->fddata->fileName);

	if(root1->lchild == NULL)
	{
		//printf("in if loop\n");


			if(root1 == tempParent->lchild)
			{
			//printf("in 2nd if loop\n");
			temp3=root1->rsibling;
			tempParent->lchild=temp3;
			child->rsibling=NULL;
			//printf("%s is been moved\n",root1->fddata->fileName);
			//free(root1);
			//deleteHash(root1->fddata);
			deleteBstElm(root1->fddata->locationPath);
			}
			else
			{
			prev=NULL;	
			ptr=tempParent->lchild;
			next=ptr->rsibling;
					while(!neighboursfound)
					{
	
							if(ptr == root1)
							{
							neighboursfound=1;

							prev->rsibling=next;
							//printf("%s is been deleted\n",root1->fddata->fileName);
							//free(root1);
							//deleteHash(root1->fddata);
							deleteBstElm(root1->fddata->locationPath);
	
							}
							else
							{
							prev=ptr;
							ptr=ptr->rsibling;
							next=ptr->rsibling;
							}
					}
			}

			root1=findfolder(temp1,destnlocationPath);
			root1=temp2;
			//printf("Destination parent %s\n:",root1->fddata->fileName);
			if(root1->lchild==NULL)
			{	
		
				
				//printf("\nlchild\n");
				root1->lchild=child;
				child->parent=temp2;

		
			}
			else
			{
				//printf("\nrsibling\n");
				root1=root1->lchild;
				while(root1->rsibling!=NULL)
				{		
				root1=root1->rsibling;
				}

				child->parent=temp2;
				root1->rsibling=child;
		
			}
			strcat(destnlocationPath,"/");
			strcat(destnlocationPath,child->fddata->fileName);
			strcpy(child->fddata->locationPath,destnlocationPath);	

	}
	
	

	return temp;

}


//-----------------------------------------------------------------------------------------------------------------------
//movefilenew
struct node * movefilecallnew(char srclocationPath[], char destnlocationPath[], struct node *root1)
{
	struct node *child,*temp,*temp1,*temp3,*tempParent,*templsibling,*temprsibling,*temp4,*ptr,*prev,*next;
	temp=root1;
	temp1=root1;
	int blkNumber;
	char tempstr[50];
	char choice;
	int neighboursfound=0;

//	printf("loctation path before findpreviousfolder:%s\n",locationPath);
	//printf("before find folder\n");
	root1=findfolder(temp1,srclocationPath);
	//printf("after find folder\n");
	root1=temp2;
	child=temp2;
	//printf("Folder to be moved(root1): %s\n",root1->fddata->fileName);

	//printf("Folder to be moved(temp2): %s\n",root1->fddata->fileName);
	//printf("Folder to be moved: %s\n",root1->fddata->locationPath);
	tempParent=root1->parent;
	temprsibling=root1->rsibling;
	templsibling=root1->lchild;
	blkNumber=root1->fddata->blockNumber;
	
	//printf("Parent of the Folder to be moved: %s\n",tempParent->fddata->fileName);
	//printf("RSibling of the Folder to be deleted: %s\n",temprsibling->fddata->fileName);
	//printf("LChild of the Folder to be deleted: %s\n",templsibling->fddata->fileName);

	if(root1->lchild == NULL)
	{
		//printf("in if loop\n");


			if(root1 == tempParent->lchild)
			{
			//printf("in 2nd if loop\n");
			temp3=root1->rsibling;
			tempParent->lchild=temp3;
			//printf("%s is been moved\n",root1->fddata->fileName);
			
			deleteHash(root1->fddata);
			deleteBstElm(root1->fddata->locationPath);
			free(root1);
			}
			else
			{
			prev=NULL;	
			ptr=tempParent->lchild;
			next=ptr->rsibling;
					while(!neighboursfound)
					{
	
							if(ptr == root1)
							{
							neighboursfound=1;

							prev->rsibling=next;
							//printf("%s is been deleted\n",root1->fddata->fileName);
							
							deleteHash(root1->fddata);
							deleteBstElm(root1->fddata->locationPath);
							free(root1);
							}
							else
							{
							prev=ptr;
							ptr=ptr->rsibling;
							next=ptr->rsibling;
							}
					}
			}

			root1=findfolder(temp1,destnlocationPath);
			root1=temp2;
			temp4=root1;
			deleteflentry(temp4);
			
			root1->fddata->blockNumber=blkNumber;
	}
	
	

	return temp;

}

void deleteflentry(struct node *root1)
{
						
						//printf("in deleteChildfile\n");
						
						
						struct freeList filefl;
						struct header hdr;
						int offset,blknumber=root1->fddata->blockNumber;
						FILE *filefldel;
						filefl.freel='0';
						filefldel=fopen(flsname,"rb+");
						offset=sizeof(hdr)+sizeof(filefl)*blknumber;
						fread(&hdr,sizeof(hdr),1,filefldel);
						int n=hdr.maxfd;
						//printf("maxfd %d\n",n);
						fseek(filefldel,offset,SEEK_SET);
						fwrite(&filefl,sizeof(filefl),1,filefldel);
						//printf("fl reset\n");

fseek(filefldel,sizeof(struct header),SEEK_SET);
	for(i=0;i<n;i++)
	{
		//printf("flist->");
		fread(&filefl,sizeof(struct freeList),1,filefldel);
		//printf("%c ",filefl.freel);
		
	}
	//printf("\n");

fclose(filefldel);

}

//-----------------------------------------------------------------------------------------------------------------------

//movedir

struct node * movedircall(char srclocationPath[], char destnlocationPath[], struct node *root1)
{
	struct node *child,*temp,*temp1,*temp3,*tempParent,*templsibling,*temprsibling,*t,*ptr,*prev,*next;
	temp=root1;
	temp1=root1;
	char tempstr[50];
	char choice;
	int neighboursfound=0;


	root1=findfolder(temp1,destnlocationPath);
	root1=temp2;
	//printf("DESTN: %s",root1->fddata->fileName);
	
	int d=strcmp(root1->fddata->fileType,"dir");
	//printf("\nd: %d\n",d);
	
	if(d!=0)
	{
	printf("movedir_FAILURE ");
	printf(ERR_VFS_MOVEDIR_07);
	printf("\n");
	return temp;
	}


	root1=findfolder(temp1,srclocationPath);
	root1=temp2;
	child=temp2;
	//printf("SRC: %s",root1->fddata->fileName);
	int s=strcmp(root1->fddata->fileType,"dir");
	//printf("\ns: %d\n",s);
	if(s!=0)
	{
	printf("movedir_FAILURE ");
	printf(ERR_VFS_MOVEDIR_04);
	printf("\n");
	return temp;
	}

	

	//printf("before tempParent\n");
	
	tempParent=root1->parent;
	//printf("after tempParent\n");
	//temprsibling=root1->rsibling;
	//templsibling=root1->lchild;
	
	//printf("Parent : %s \n",tempParent->fddata->fileName);
	if(root1->lchild == NULL)
	{
		//printf("in if loop\n");


			if(root1 == tempParent->lchild)
			{
			//printf("in 2nd if loop\n");
			temp3=root1->rsibling;
			tempParent->lchild=temp3;
			child->rsibling=NULL;
			//printf("%s is been moved\n",root1->fddata->fileName);
			//free(root1);
			}
			else
			{
			prev=NULL;	
			ptr=tempParent->lchild;
			next=ptr->rsibling;
					while(!neighboursfound)
					{
	
							if(ptr == root1)
							{
							neighboursfound=1;

							prev->rsibling=next;
							//printf("%s is been deleted\n",root1->fddata->fileName);
							//free(root1);
	
							}
							else
							{
							prev=ptr;
							ptr=ptr->rsibling;
							next=ptr->rsibling;
							}
					}
			}

	root1=findfolder(temp1,destnlocationPath);
	root1=temp2;
	//printf("Destination parent %s\n:",root1->fddata->fileName);
	if(root1->lchild==NULL)
	{	
		
				
		//printf("\nlchild\n");
		root1->lchild=child;
		child->parent=temp2;

		
	}
	else
	{
		//printf("\nrsibling\n");
		root1=root1->lchild;
		while(root1->rsibling!=NULL)
		{		
		root1=root1->rsibling;
		}

		child->parent=temp2;
		root1->rsibling=child;
		
	}
	
	if(strcmp(destnlocationPath,"/")!=0)
	strcat(destnlocationPath,"/");

	//printf("Destnlocpath: %s\n",destnlocationPath);
	strcat(destnlocationPath,child->fddata->fileName);
	strcpy(child->fddata->locationPath,destnlocationPath);	

	}
	
	else
	{
	//printf(" %s is not empty\n",root1->fddata->fileName);
	//printf("If you still want to delete %s press y",root1->fddata->fileName);
	
			
					if(root1 == tempParent->lchild)
					{
					temp3=root1->rsibling;
					tempParent->lchild=temp3;
					child->rsibling=NULL;
					//printf("%s is been moved\n",root1->fddata->fileName);
					//free(root1);
					}
					else
					{
					prev=NULL;	
					ptr=tempParent->lchild;
					next=ptr->rsibling;
							while(!neighboursfound)
							{
	
							if(ptr == root1)
							{
							neighboursfound=1;

							prev->rsibling=next;
							//printf("%s is been deleted\n",root1->fddata->fileName);
							//free(root1);
	
							}
							else
							{
							prev=ptr;
							ptr=ptr->rsibling;
							next=ptr->rsibling;
							}
							}
					}
	root1=findfolder(temp1,destnlocationPath);
	root1=temp2;
	//printf("Destination %s\n:",root1->fddata->fileName);
	if(root1->lchild==NULL)
	{	
		
				
		//printf("\nlchild\n");
		//printf("\n");
		root1->lchild=child;
	//printf("2\n");
		child->parent=temp2;
	//printf("1\n");

		
	}
	else
	{
		//printf("\nrsibling\n");
		root1=root1->lchild;
		while(root1->rsibling!=NULL)
		{		
		root1=root1->rsibling;
		}

		child->parent=temp2;
		root1->rsibling=child;
		
	}
	
	

	updatelocPath_subTree(child,destnlocationPath);
	//printf("before updt\n");
	
			
	}

	//printf("Previous folder: %s\n",tempParent->fddata->fileName);

	return temp;

}


//-----------------------------------------------------------------------------------------------------------------------
struct node * findfolder(struct node *temp1,char location[])
{
	
	if(temp1 == NULL) return 0;
	if(strcmp(temp1->fddata->locationPath,location)==0)
	{	
		
				
		temp2=temp1;
		//printf("%s",temp2->fddata->fileName);
		 return temp1;
	}
	//printf("\nhello\n");
	findfolder(temp1->rsibling,location);
	findfolder(temp1->lchild,location);
}

//-----------------------------------------------------------------------------------------------------------------------
struct node * updatelocPath_subTree(struct node *tempupdate,char destnlocationPath[])
{
	
	if(tempupdate == NULL) return 0;
	strcpy(destnlocationPath,tempupdate->parent->fddata->locationPath);
	
	if(strcmp(destnlocationPath,"/")!=0)
	strcat(destnlocationPath,"/");

	strcat(destnlocationPath,tempupdate->fddata->fileName);
	strcpy(tempupdate->fddata->locationPath,destnlocationPath);
	//printf("Parent : %s\n",destnlocationPath);
	//printf("\nupdt hello\n");
	
	updatelocPath_subTree(tempupdate->lchild,destnlocationPath);
	updatelocPath_subTree(tempupdate->rsibling,destnlocationPath);
	return NULL;
}
//-----------------------------------------------------------------------------------------------------------------------

printfolder(struct node *temp1)
{
	if(temp1==NULL) return 0;
	
	printf("->%s(%s)\n",temp1->fddata->fileName,temp1->fddata->fileType);
	printfolder(temp1->rsibling);
	printfolder(temp1->lchild);
	
	//if(temp1->rsibling==NULL) printf("\n");
}
//-----------------------------------------------------------------------------------------------------------------------

void writefd(char fileSystemName[],struct node *root)
{
	int size1,n,i;
	
		
		
		FILE *fp;
		fp=fopen(fileSystemName,"rb+");
		struct header h;
		fread(&h,sizeof(struct header),1,fp);
		n=h.maxfd;
		struct freeList fl;
		struct fileDescriptor *filefd;
		filefd=root->fddata;
		//printf("%s\n",filefd->fileName);
		//printf("%s\n",filefd->locationPath);
		size1=sizeof(struct header)+n*sizeof(struct freeList)+count*sizeof(struct fileDescriptor);
		fseek(fp,size1,SEEK_SET);
		count++;
		fwrite(filefd,sizeof(struct fileDescriptor),1,fp);
		//printf("%c",filefd->isfull);
		free(root);
		//free(root1);
		fclose(fp);
}

	
int unmount_narry(char fileSystemName[],struct node *root)
{
	//struct node * temp1;
	if(root==NULL) return 0;
	writefd(fileSystemName,root);
	unmount_narry(fileSystemName,root->rsibling);
	unmount_narry(fileSystemName,root->lchild);
}		
//-----------------------------------------------------------------------------------------------------------------------

void print(char f[])
{
	struct node *root;
	struct header h;
	//struct fileDescriptor fd;
	struct freeList fl;
	struct fileDescriptor filefd;
	int choice,size1,n,i;
	char locationPath[50],childName[50];
	FILE *fp;	
	fp=fopen(f,"rb+");

	
	if(fp==NULL) 
	{
		//printf("Invalid file system !\n");
		return NULL;
	}
		fread(&h,sizeof(struct header),1,fp);
		n=h.maxfd;
		size1=sizeof(struct header)+n*sizeof(struct freeList);
		fseek(fp,size1,SEEK_SET);
	
	for(i=0;i<n;i++)
	{
		if(filefd.isfull == '1') {
		fread(&filefd,sizeof(struct fileDescriptor),1,fp);
		strcpy(childName,filefd.fileName);
		strcpy(locationPath,filefd.locationPath);
		//printf("%s",childName);
		//printf("%c",filefd.isfull);
		//printf("\n");
	}
		
	}
}
//-----------------------------------------------------------------------------------------------------------------------
void reinitializefd(char fsname[])
{
struct node *root;
	struct header h;
	//struct fileDescriptor fd;
	struct freeList fl;
	struct fileDescriptor filefd;
	int choice,size1,n,i;
	char locationPath[50],childName[50];
	FILE *fp;	
	fp=fopen(fsname,"rb+");

	//printf("FILESYS %s\n",fsname);
	if(fp==NULL) 
	{
		//printf("Invalid file system !\n");
		
	}
		fread(&h,sizeof(struct header),1,fp);
		n=h.maxfd;
		int temp_size=n;
		//printf("n=maxfd : %d\n",i);
		size1=sizeof(struct header)+temp_size*sizeof(struct freeList);
		fseek(fp,size1,SEEK_SET);
	//n=h.maxfd;
	for(i=0;i<h.maxfd;i++)
	{
		//fread(&filefd,sizeof(struct fileDescriptor),1,fp);
		struct fileDescriptor filefd1;
		filefd1.isfull='0';
		fwrite(&filefd1,sizeof(struct fileDescriptor),1,fp);
		//printf("%d %d\n",i,n);
	}

	fclose(fp);
}

int makedircall(char childName[],char locationPath[],struct node *root1)
{

			char filename1[30];
			char prevlocationpath[100],locationpathfinal[100],prevfileName[50];
			char delims[] = "/";
			char *result = NULL;
			char tempstr[50],tempstr1[50];
			char locatiopathfinal[100];
			strcpy(locationpathfinal,locationPath);
			//printf("loc in makedir call:%s\n",locationPath);
			result = strtok( locationPath, delims );
			strcpy(prevlocationpath,"/");
			while( result != NULL ) 
			{
				if(result!=NULL)
				{
				strcpy(filename1,result);
				temp2=NULL;
				//printf( "result is %s\n", result );		//here result is splitted file name
				struct node *t1=findDirectory(root1,filename1);
				t1=temp2;
				if(t1!=NULL)
				{
					strcpy(prevlocationpath,t1->fddata->locationPath);
					
					//printf("in makedir call:%s\n",t1->fddata->locationPath);

				}
				else
				{
					
					if(fd_count<=0)
					return 0;
		
					root1=createChild(filename1,prevlocationpath,root1);
					//printf("prevloc:%s\n",prevlocationpath);
					//printf("not found\n");
					strcpy(prevfileName,result);
					if(strcmp(prevlocationpath,"/")==0)
					strcpy(tempstr,"");
					else
					strcpy(tempstr,"/");

					strcat(tempstr,prevfileName);
					//strcat(prevfileName,tempstr);
					strcpy(tempstr1,prevlocationpath);
					strcat(tempstr1,tempstr);
					strcpy(prevlocationpath,tempstr1);

				}
				}
					result=strtok(NULL,delims);
					
			}
			//printf("ccname:%s\nlocpathhhhhhhhhhh:%s\n",childName,locationPath);
			root1=createChild(childName,locationpathfinal,root1);
			return 1;
}

struct node * findDirectory(struct node *temp1,char fileName[])
{
	
	if(temp1 == NULL) return NULL;
	if(strcmp(temp1->fddata->fileName,fileName)==0)
	{	
		temp2=temp1;	
		return temp1;
	//	printf("\nin if\n");
		
	}
	//printf("\nhello\n");
	findDirectory(temp1->rsibling,fileName);
	findDirectory(temp1->lchild,fileName);
}

int listdir_new(char dir_path[], int flag, char outputfile[],struct node *root)
{
    FILE *fp_out;
    fp_out=fopen(outputfile,"wb+");
    if(fp_out==NULL)
    {
    printf("listdir_FAILURE  ");
    printf(ERR_VFS_LISTDIR_04);
    printf("\n");
    return 1;
    }
    //printf("file opened\n");
    struct node* temp_listdir=root;
    write_to_file(temp_listdir, flag,fp_out, dir_path);
    fclose(fp_out);
    return 0;
    }    


void write_to_file(struct node* temp_listdir, int flag, FILE * fp_out,char dir_path[])
{

    char dir_name[50],file_type[10];
    int fl=0;
    char *newtab = " ";
    char *newline = "\n";
    //printf("in the function write to file \n");
        
    struct node * list_temp=findfolder(temp_listdir,dir_path);
    list_temp=temp2;
        

    if(flag==0)
    {
        list_temp=list_temp->lchild;
        while(list_temp!=NULL)
        {
            fprintf(fp_out,"%s",dir_name);
            fprintf(fp_out,"%s",newtab);
            fprintf(fp_out,"%s",file_type);
            list_temp=list_temp->rsibling;
        }
            
    }
    else if(flag==1)
    {
        traverse_listdir(list_temp,fp_out);
    }
}

    

traverse_listdir(struct node* temp_listdir1, FILE *fp_out)
{    
    
        char dir_name1[50],file_type1[10];
        if(temp_listdir1==NULL) 
        return 0;
        
        strcpy(dir_name1,temp_listdir1->fddata->fileName);
        strcpy(file_type1,temp_listdir1->fddata->fileType);
        fprintf(fp_out,"%s",dir_name1);
        char *newtab = " ";
        fprintf(fp_out,"%s",newtab);
        fprintf(fp_out,"%s",file_type1);
        char *newline = "\n";
        fprintf(fp_out,"%s",newline);
        
        //if(temp_listdir1->rsibling!=NULL)
        traverse_listdir(temp_listdir1->rsibling,fp_out);
        traverse_listdir(temp_listdir1->lchild,fp_out);
}
int listfile_new(char filePath[],char filename_out[],char fileSystemName[],struct node* root)
{
        //printf("%s",fileSystemName);
        FILE *f_out;
        int rflag=1;
        f_out=fopen(filename_out,"w");
        //printf("file opened");
	if(f_out==NULL)
	{	printf("listfile_FAILURE  ");
		printf(ERR_VFS_LISTFILE_03);
		printf("\n");
		return 2;
		
	}
        struct node* temp_listfile=root;
       // printf("root ");
	
        rflag=findfile(temp_listfile, f_out,fileSystemName,filePath,rflag);
	/*
        if (rflag==1){
        printf("listfile_FAILURE  ");
        printf(ERR_VFS_LISTFILE_01);
        }
        else if(rflag==0){
                                printf("listfile_SUCCESS");
                        }
            taken care of in vfsdriver itself*/    
        return 0;
}

int findfile(struct node* temp_listfile, FILE * f_out, char fileSystemName[],char filePath[],int rflag)
{
        //printf("in find folder");
        int blkNumber;
        int size1,n;
        FILE *fp;       
        fp=fopen(fileSystemName,"r+");
        //printf("file system opened");
	
        struct header h;
		struct node* temp5;
                fread(&h,sizeof(struct header),1,fp);
                n=h.maxfd;
                struct freeList fl;
                struct fileDescriptor *filefd;
                struct Block bd;
                filefd=temp_listfile->fddata;
             // printf("%s",filefd->fileName);
		
                 
			temp5=findfolder(temp_listfile,filePath);
			//printf("testing");

			
			
			temp5=temp2;
                     if(strcmp(temp5->fddata->fileType,"text")!=0)
                        {
			printf("listfile_FAILURE  ");
                        printf(ERR_VFS_LISTFILE_02);
			printf("\n");
                        return 2;
                        }
			
                        blkNumber=temp5->fddata->blockNumber;

                        size1=sizeof(struct header)+n*sizeof(struct freeList)+n*sizeof(struct fileDescriptor)+ blkNumber* sizeof(struct Block) ;

                        fseek(fp,size1,SEEK_SET);

                        write_to_file_content(fp,f_out,bd);
                        
return 0;
}
void write_to_file_content(FILE *fp, FILE* f_out,struct Block bd)
{
//struct Block *bd_ptr;
        int k=0;
        char ch;
        //printf("%d",blockSize);
        while(1)
                {
                        ch = fgetc(fp);
                        if(ch=='\0')
                        break;
                        fputc(ch,f_out);
        //              printf("%c",ch); 

                }
        //fread(&bd,sizeof(struct Block),1,fp);
//printf("%s", bd.text);   
//fwrite(&bd,sizeof(struct Block),1,f_out);

        fclose(f_out);
        //fprintf(f_out,"%s",rf);
        //printf("one char wrtn");
}
